package site.xuxingcan.NettyUtil;

import com.google.gson.Gson;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.AttributeKey;
import site.xuxingcan.Model.CardModel;
import site.xuxingcan.Model.LoginModel;
import site.xuxingcan.Model.RoomActionModel;
import site.xuxingcan.Model.UserCardModel;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;

/**
 * Created by xuxingcan on 16-7-26.
 */
public class DataUtil {
    public static Gson gson = new Gson();
    /**
     * userName AuthModel<p></p>
     * todo 保存到文件
     */
    private static HashMap<String, AuthModel> authModelHashMap = new HashMap<>();
    private static HashMap<Integer, RoomModel> roomHashMap = new HashMap<>();
    private static ArrayList<Integer> availableRoomNumber = new ArrayList<>();

    static {
        for (int i = 100000; i < 999999; i++) {
            availableRoomNumber.add(i);
        }
    }

    public static boolean isUserOk(String userName, String randomString) {
        if (!authModelHashMap.containsKey(userName)) {
            return false;
        } else {
            AuthModel authModel = authModelHashMap.get(userName);
            if (authModel.randomString.equalsIgnoreCase(randomString)) {
                return true;
            } else {
                return false;
            }
        }
    }

    public static void shutDownSocket(String s) {
        if (authModelHashMap.containsKey(s)) {
            AuthModel authModel = authModelHashMap.remove(s);
            authModel.channelHandlerContext.close();
        }
    }

    public static void addNewShutDownOldIfNecessary(LoginModel loginModel, ChannelHandlerContext channelHandlerContext) {
        if (authModelHashMap.containsKey(loginModel.getUserName())) {
            AuthModel authModel = authModelHashMap.remove(loginModel.getUserName());
            authModel.channelHandlerContext.close();
        }
//        if(authModelHashMap.containsValue(channelHandlerContext)){
//            authModelHashMap.re
//        }
        AuthModel authModel = new AuthModel(loginModel.getUserName(), loginModel.getRandomString(), channelHandlerContext);
        authModelHashMap.put(loginModel.getUserName(), authModel);
    }

    public static void getInRoom(RoomActionModel roomActionModel) {
        if (authModelHashMap.containsKey(roomActionModel.getUserName())) {
            AuthModel authModel = authModelHashMap.get(roomActionModel.getUserName());
            if (authModel.getRoomNumber() != -1) {
                roomActionModel.setResult(false);
            }
            if (roomHashMap.containsKey(roomActionModel.getRoomNumber())) {
                RoomModel roomModel = roomHashMap.get(roomActionModel.getRoomNumber());
                if (roomModel.addUser(authModel)) {
                    authModel.setRoomNumber(roomActionModel.getRoomNumber());
//                    if (roomModel.isFull()) {
//                        // TODO: 16-7-26 房间满了 开始游戏
//                        roomModel.startGame();
//                    }
                    roomActionModel.setResult(true);
                } else {
                    roomActionModel.setResult(false);
                }
            } else {
                roomActionModel.setResult(false);
            }
        } else {
            roomActionModel.setResult(false);
        }
    }

    public static void outOfRoom(RoomActionModel roomActionModel) {
        if (authModelHashMap.containsKey(roomActionModel.getUserName())) {
            AuthModel authModel = authModelHashMap.get(roomActionModel.getUserName());
            if (authModel.getRoomNumber() == -1) {
                roomActionModel.setResult(false);
                return;
            }
            if (roomHashMap.containsKey(authModel.getRoomNumber())) {
                RoomModel roomModel = roomHashMap.get(authModel.getRoomNumber());
                if (roomModel.removeUser(roomActionModel.getUserName())) {
                    if (roomModel.isEmpty()) {
                        roomHashMap.remove(authModel.getRoomNumber());
                        availableRoomNumber.add(authModel.getRoomNumber());
                    }
                    authModel.setRoomNumber(-1);
                    roomActionModel.setResult(true);
                } else {
                    authModel.setRoomNumber(-1);
                    roomActionModel.setResult(true);
                }
            } else {
                authModel.setRoomNumber(-1);
                roomActionModel.setResult(false);
            }
        } else {
            roomActionModel.setResult(false);
        }
    }

    public static void getNewRoom(RoomActionModel roomActionModel) {
        if (authModelHashMap.containsKey(roomActionModel.getUserName())) {
            AuthModel authModel = authModelHashMap.get(roomActionModel.getUserName());
            if (authModel.getRoomNumber() != -1) {
                roomActionModel.setResult(false);
                return;
            }
            if (availableRoomNumber.size() > 0) {
                RoomModel roomModel = new RoomModel(availableRoomNumber.remove(0));
                roomModel.addUser(authModel);
                roomHashMap.put(roomModel.roomNumber, roomModel);
                authModel.setRoomNumber(roomModel.roomNumber);
                roomActionModel.setRoomNumber(roomModel.roomNumber);
                roomActionModel.setResult(true);
            } else {
                roomActionModel.setResult(false);
            }
        } else {
            roomActionModel.setResult(false);
        }
    }

    static class AuthModel {
        public String userName;
        public String randomString;
        public int roomNumber = -1;
        public ChannelHandlerContext channelHandlerContext;

        public AuthModel(String userName, String randomString, ChannelHandlerContext channelHandlerContext) {
            this.userName = userName;
            this.randomString = randomString;
            this.channelHandlerContext = channelHandlerContext;
        }

        public int getRoomNumber() {
            return roomNumber;
        }

        public void setRoomNumber(int roomNumber) {
            this.roomNumber = roomNumber;
        }
    }

    public static final AttributeKey<RoomModel> NETTY_ROOM_KEY = AttributeKey.valueOf("NETTY_ROOM_KEY");

    public static class RoomModel {
        public int roomNumber;
        public AuthModel authModel1 = null;
        public AuthModel authModel2 = null;
        public AuthModel authModel3 = null;
        public AuthModel authModel4 = null;
        public UserCardModel userCardModel1 = null;
        public UserCardModel userCardModel2 = null;
        public UserCardModel userCardModel3 = null;
        public UserCardModel userCardModel4 = null;
        private ArrayList<CardModel> cardModelArrayList;

        public RoomModel(int roomNumber) {
            this.roomNumber = roomNumber;
        }

        public void startGame() {
            if (!isFull()) {
                return;
            }
//            authModel1.channelHandlerContext.channel().attr(NETTY_ROOM_KEY).set(this);
//            authModel2.channelHandlerContext.channel().attr(NETTY_ROOM_KEY).set(this);
//            authModel3.channelHandlerContext.channel().attr(NETTY_ROOM_KEY).set(this);
//            authModel4.channelHandlerContext.channel().attr(NETTY_ROOM_KEY).set(this);
            cardModelArrayList = new ArrayList<>();
            for (int type = 1; type <= 3; type++) {
                for (int number = 1; number <= 9; number++) {
                    for (int i = 0; i < 4; i++) {
                        cardModelArrayList.add(new CardModel(type, number));
                    }
                }
            }
            Collections.shuffle(cardModelArrayList);
            userCardModel1 = new UserCardModel(authModel1.userName);
            for (int j = 0; j < 13; j++) {
                userCardModel1.addCurrentCardModels(cardModelArrayList.remove(0));
            }
            Collections.sort(userCardModel1.getCurrentCardModels());

            userCardModel2 = new UserCardModel(authModel2.userName);
            for (int j = 0; j < 13; j++) {
                userCardModel2.addCurrentCardModels(cardModelArrayList.remove(0));
            }
            Collections.sort(userCardModel2.getCurrentCardModels());

            userCardModel3 = new UserCardModel(authModel3.userName);
            for (int j = 0; j < 13; j++) {
                userCardModel3.addCurrentCardModels(cardModelArrayList.remove(0));
            }
            Collections.sort(userCardModel3.getCurrentCardModels());

            userCardModel4 = new UserCardModel(authModel4.userName);
            for (int j = 0; j < 13; j++) {
                userCardModel4.addCurrentCardModels(cardModelArrayList.remove(0));
            }
            Collections.sort(userCardModel4.getCurrentCardModels());

            userCardModel1.setHandCardModel(cardModelArrayList.remove(0));

            authModel1.channelHandlerContext.writeAndFlush(gson.toJson(userCardModel1));
            authModel2.channelHandlerContext.writeAndFlush(gson.toJson(userCardModel2));
            authModel3.channelHandlerContext.writeAndFlush(gson.toJson(userCardModel3));
            authModel4.channelHandlerContext.writeAndFlush(gson.toJson(userCardModel4));
        }

        public boolean isEmpty() {
            return authModel1 == null && authModel2 == null && authModel3 == null && authModel4 == null;
        }

        public boolean isFull() {
            return authModel1 != null && authModel2 != null && authModel3 != null && authModel4 != null;
        }

        public boolean removeUser(String userName) {
            if (authModel1 != null && authModel1.userName.equalsIgnoreCase(userName)) {
                authModel1.channelHandlerContext.channel().attr(NETTY_ROOM_KEY).set(null);
                authModel1 = null;
                return true;
            }
            if (authModel2 != null && authModel2.userName.equalsIgnoreCase(userName)) {
                authModel2.channelHandlerContext.channel().attr(NETTY_ROOM_KEY).set(null);
                authModel2 = null;
                return true;
            }
            if (authModel3 != null && authModel3.userName.equalsIgnoreCase(userName)) {
                authModel3.channelHandlerContext.channel().attr(NETTY_ROOM_KEY).set(null);
                authModel3 = null;
                return true;
            }
            if (authModel4 != null && authModel4.userName.equalsIgnoreCase(userName)) {
                authModel4.channelHandlerContext.channel().attr(NETTY_ROOM_KEY).set(null);
                authModel4 = null;
                return true;
            }
            return false;
        }

        public boolean addUser(AuthModel authModel) {
            if (authModel1 == null) {
                authModel1 = authModel;
                authModel1.channelHandlerContext.channel().attr(NETTY_ROOM_KEY).set(this);
                return true;
            }
            if (authModel2 == null) {
                authModel2 = authModel;
                authModel2.channelHandlerContext.channel().attr(NETTY_ROOM_KEY).set(this);
                return true;
            }
            if (authModel3 == null) {
                authModel3 = authModel;
                authModel3.channelHandlerContext.channel().attr(NETTY_ROOM_KEY).set(this);
                return true;
            }
            if (authModel4 == null) {
                authModel4 = authModel;
                authModel4.channelHandlerContext.channel().attr(NETTY_ROOM_KEY).set(this);
                return true;
            }
            return false;
        }
    }
}
